#ifndef __PVMAPI_H__
#define __PVMAPI_H__

#include "pvm/pvmdefs.h"
#include "pvm/pvmtypes.h"

#if defined(__cplusplus)
class IPvmInStream;
extern "C"
{
#endif/*__cplusplus*/

/*
	Voice's callback function definition.
	return values:
	zero - resume playing
	less than zero - stop voice
	greater than zero - pause voice
*/
typedef pvm_int32 (PVMCALL *TVoiceCallbackProc)(pvm_int32 chanelNum, pvm_uint32 voiceState, pvm_int32 currentPositionMs, void* param);
/*!!! Important! Do not call any PVM API function from callback! This can lead to deadlock.*/
typedef void (PVMCALL *TFormatEnumCallbackProc)(pvm_uint32 chanelsNum, pvm_uint32 bitsPerSample, pvm_uint32 samplesPerSecond, void* param);

/*
	PVM Enumerations:
*/

/*
	Seek origin.
*/

typedef enum
{
	EPVM_SEEK_BEGIN = 0,
	EPVM_SEEK_CURRENT = 1,
	EPVM_SEEK_END = 2
} TPvmSeek;

/*
	Driver flags.
*/

typedef enum
{
	EPVM_DTYPE_OUTPUT = 1,
	EPVM_DTYPE_INPUT = 2,
	EPVM_DTYPE_DEVICE = 4,
	EPVM_DTYPE_STREAM_WRITER = 8,
} TPvmDriverTypeAndFlags;

typedef enum
{
	EPARAM_VOLUME = 1,
	EPARAM_PANNING = 2,
	EPARAM_RATE = 3,
} TPvmParamId;

typedef enum
{
	EVOICE_STOPPED = 0,
	EVOICE_PLAYING = 1,
	EVOICE_PAUSED = 3
} TPvmVoiceState;

typedef enum
{
	EPVM_LOADTOMEMORY=1,
	EPVM_DECODETOPCM=2,
} TPvmPVMLoadAudioOptions;

typedef enum
{
	E_LINEAR_DISTANCE = 1,
	E_LINEAR_DISTANCE_CLAMPED = 2,
	E_INVERSE_DISTANCE = 4,
	E_INVERSE_DISTANCE_CLAMPED = 8,
	E_EXPONENT_DISTANCE = 16,
	E_EXPONENT_DISTANCE_CLAMPED = 32
} TPvmDistanceModel;

typedef enum
{
	E_3D_NONE = 0,
	E_3D_HARDWARE = 1,
	E_3D_SOFTWARE_FLOAT = 2,
	E_3D_SOFTWARE_FIXED = 4,

	E_3D_OPTIMAL = -1,
	E_3D_BEST = -2,
	E_3D_FAST = -3,
} TPvm3DSupportFlags;

typedef enum
{
	PVM_VOICE_FREE = 0x80000000,
	PVM_VOICE_FREE_HARDWARE = 0x80000000|1,
	PVM_VOICE_FREE_SOFTWARE = 0x80000000|2,
	PVM_VOICE_FREE_3DHARDWARE = 0x80000000|4
} TPvmStartFlags;

typedef enum
{
	PVM_MMGR_NO_THREAD_SYNC = 1
} TPvmMmgrFlag;

typedef enum
{
	E_MMGR_DOUG_LEA_ALLOCATOR = 1,
	E_MMGR_DEFAULT = E_MMGR_DOUG_LEA_ALLOCATOR
} TPvmMMGRType;

typedef struct _IPVMReadCallbacks {
	pvm_size (*Read)(void *src, void *buf, pvm_size size);
	pvm_bool (*Seek)(void *src, pvm_file_size pos, int origin);
	pvm_file_size (*Tell)(void *src);
	void (*Close)(void *src);
	pvm_file_size (*Size)(void *src);
	void* (*OpenCopy)(void *src);//return NULL if not supported - so only one chanel can play at once
	pvm_bool (*Seekable)(void *src);//return non zero if Seek can be performed
	pvm_bool (*Eof)(void *src);
	void* param;
} IPVMReadCallbacks;

typedef struct _IPVMWriteCallbacks {
	pvm_size (*Write)(void *src, void *buf, pvm_size size);
	pvm_bool (*Seek)(void *src, pvm_file_size pos, int origin);
	pvm_file_size (*Tell)(void *src);
	void (*Close)(void *src);
	pvm_file_size (*Size)(void *src);
	pvm_bool (*Seekable)(void *src);//return non zero if Seek can be performed
	void* param;
} IPVMWriteCallbacks;

typedef struct _IPVMReadCallbacksSource {
	IPVMReadCallbacks* callBacks;
	void* src;
} IPVMReadCallbacksSource;

typedef struct _IPVMWriteCallbacksSource {
	IPVMWriteCallbacks* callBacks;
	void* src;
} IPVMWriteCallbacksSource;

struct _IPVMMemoryManager;

typedef struct
{
	void* param;//can be used by allocator to define heap or any other purpose
	void* (*Malloc)(void* param, pvm_size size);
	void (*Free)(void* param, void *ptr);
	void* (*Realloc)(void* param, void *ptr, pvm_size size);
	int (*GetFlags)(void);
	void (*Destory)(void* mmgr);
} IPVMMemoryManager;

/*
	PVM handle types:
*/

typedef void* PVMHANDLE;
typedef PVMHANDLE PVMAUDIO;
typedef PVMHANDLE PVMAUDIOCACHE;
typedef PVMHANDLE PVMDEVICE;
typedef PVMHANDLE PVM3DHANDLE;

/*
	Libary version structure:
*/

typedef struct _PvmVersionInfo
{
	pvm_int32 versionHigh;
	pvm_int32 versionLow;
	pvm_int32 revision;
	const pvm_char* buildDate;
	const pvm_char* commitDate;

} PvmVersionInfo;

/*
	Audio format structure:
*/

typedef struct _PvmFormatInfo
{
	pvm_uint32 chanelsNum;
	pvm_uint32 bitsPerSample;
	pvm_uint32 samplesPerSecond;
} PvmFormatInfo;

/*
	Next functions can be called before initialization:
*/

/*
	These functions returns verision of PVM libary
*/

PVMAPI pvm_int32 PVMCALL PVMGetVersion();//version hi<<24 || version low<<16 || revision
PVMAPI pvm_bool PVMCALL PVMGetVersionFull(PvmVersionInfo *versionInfo);

/*
This functoin can be called before PVMInit to create memory mamanger.
You can pass this mmgr to PVMInit.
Do not forget to call PVMMemoryManagerDestroy after PVMDeinit
*/
PVMAPI IPVMMemoryManager* PVMCALL PVMMemoryManagerCreate(TPvmMMGRType mmgrType, void* heapBuffer, pvm_size heapSize);
PVMAPI void PVMCALL PVMMemoryManagerDestroy(IPVMMemoryManager* mmgr);

/*
	Library initialization/deinitialization
	PVMInit() returns non false value on success		
*/

PVMAPI pvm_bool PVMCALL PVMInit(IPVMMemoryManager* customMemoryManager);
PVMAPI void PVMCALL PVMDeinit();
PVMAPI pvm_bool PVMCALL PVMInitialized();

/*
	Call this function periodically (e.g. - once per frame in games) to free resources on some platforms (e.g. marmalade).
*/
PVMAPI void PVMCALL PVMOnIdle();

/*
	Drivers information and loading
*/

PVMAPI pvm_int32 PVMCALL PVMGetDriversCount();
/*

	PVMGetDriverNameShort and PVMGetDriverNameFull functions return number of pvm_char copyed to buffer
	-1 if no such device 
	0 if buffer are not enough to hold string
	call with buffer or maxLength set to NULL to get length of name including zero termination character
*/
PVMAPI pvm_int32 PVMCALL PVMGetDriverNameShort(pvm_uint32 nDriverNum, pvm_char* buffer, pvm_uint32 maxChars);
PVMAPI pvm_int32 PVMCALL PVMGetDriverNameFull(pvm_uint32 nDriverNum, pvm_char* buffer, pvm_uint32 maxChars);
PVMAPI pvm_uint32 PVMCALL PVMGetDriverTypeAndFlags(pvm_uint32 nDriverNum);//return driver type or 0 on error

PVMAPI pvm_bool PVMCALL PVMLoadDriver(pvm_uint32 nDriver);

PVMAPI void PVMCALL PVMDeviceClose(PVMDEVICE device);
PVMAPI pvm_bool PVMCALL PVMGetDriverOption(pvm_uint32 nDriver, const pvm_char* optionName, void* optionVal, pvm_uint32* optionSize);
PVMAPI pvm_bool PVMCALL PVMSetDriverOption(pvm_uint32 nDriver, const pvm_char* optionName, void* optionVal, pvm_uint32 optionSize);

/*
	Device common functions
*/

/*
	Device options
*/
PVMAPI pvm_int32 PVMCALL PVMGetDeviceOption(PVMDEVICE device, const pvm_char* optionName, void* optionVal, pvm_uint32* optionSize);
PVMAPI pvm_int32 PVMCALL PVMSetDeviceOption(PVMDEVICE device, const pvm_char* optionName, void* optionVal, pvm_uint32 optionSize);


/*
	Next functions are used to control state of the device
*/
PVMAPI void PVMCALL PVMSuspendDevice(PVMDEVICE device);
PVMAPI void PVMCALL PVMResumeDevice(PVMDEVICE device);
PVMAPI pvm_int32 PVMCALL PVMIsSuspendedDevice(PVMDEVICE device);//1 - suspended, 0 - runing, -1 error

/*
	Output device functions
*/

/*
	Open output device
*/
#if defined(__cplusplus)
PVMAPI PVMDEVICE PVMCALL PVMDeviceOutOpen(pvm_uint32 nDriver, pvm_int32 nDeivce, pvm_uint32 maxVoices, pvm_uint32 preferedSamplesPerSec, pvm_uint32 preferedBitsPerSample, pvm_uint32 preferedChanelsNum, void *additionalInfo=0, pvm_uint32 infoSize=0);
#else
PVMAPI PVMDEVICE PVMCALL PVMDeviceOutOpen(pvm_uint32 nDriver, pvm_int32 nDeivce, pvm_uint32 maxVoices, pvm_uint32 preferedSamplesPerSec, pvm_uint32 preferedBitsPerSample, pvm_uint32 preferedChanelsNum, void *additionalInfo, pvm_uint32 infoSize);
#endif

/*
	Next functions are used to get device information
*/
PVMAPI pvm_uint32 PVMCALL PVMDevicesOutNum(pvm_uint32 nDriver);
PVMAPI pvm_int32 PVMCALL PVMGetDeviceOutName(pvm_uint32 nDriver, pvm_int32 nDevice, pvm_char* buffer, pvm_uint32 maxLength);
PVMAPI pvm_int32 PVMCALL PVMDeviceGetCPUUsage(PVMDEVICE device);//return -1 on error
PVMAPI pvm_uint32 PVMCALL PVMDeviceOutHardwareChanels(pvm_uint32 nDriver, pvm_int32 nDevice);//return maximum chanels that can be mixed in harware
PVMAPI pvm_bool PVMCALL PVMDeviceOutEnumModes(pvm_uint32 nDriver, pvm_int32 nDeivce, TFormatEnumCallbackProc enumProc, void *param);//return non zero on succes
PVMAPI pvm_bool PVMCALL PVMGetDeviceOutActualFormat(PVMDEVICE device, PvmFormatInfo* formatInfo);//return false on error
/*
	returns number of formats filled, -1 on error
	to get max formats count pass NULL to formats
*/
PVMAPI pvm_int32 PVMCALL PVMDeviceOutGetModes(pvm_uint32 nDriver, pvm_int32 nDeivce, PvmFormatInfo* formats, pvm_uint32 maxFormats);


/*
	set sound buffer size in milliseconds, greater length - greater latency
*/
PVMAPI void PVMCALL PVMDeviceOutSetBufferLengthMs(PVMDEVICE device, pvm_uint32 bufferSize);
/*
	retuns current buffer size in milliseconds
	note that buffer does not changed in call of SetBufferLengthMs
	it's size will be changed in threading procedure
	so it can be some delay between SetBufferLengthMs and real buffer realocation
*/
PVMAPI pvm_int32 PVMCALL PVMDeviceOutGetBufferRealLengthMs(PVMDEVICE device);

/*
	volume are limited up to 256
*/
PVMAPI void PVMCALL PVMDeviceOutSetGlobalVolume(PVMDEVICE device, pvm_uint32 volume);
PVMAPI pvm_int32 PVMCALL PVMDeviceOutGetGlobalVolume(PVMDEVICE device);

/*
	Audio output device format information
*/
PVMAPI pvm_uint32 PVMCALL PVMDeviceOutGetChanelsNum(PVMDEVICE device);
PVMAPI pvm_uint32 PVMCALL PVMDeviceOutGetBitsPerSample(PVMDEVICE device);
PVMAPI pvm_uint32 PVMCALL PVMDeviceOutGetSamplesPerSecond(PVMDEVICE device);

/*
	Returns maximal callback period in milliseconds
*/
PVMAPI pvm_uint32 PVMCALL PVMGetAudioMaxCallbackPeriodMs();


/*
	Audio file functions:
*/

/*
	Open audio file (sample/music).
*/
PVMAPI PVMAUDIO PVMCALL PVMAudioOpenCallbacks(IPVMReadCallbacks *callbacks, void *src, pvm_uint32 options, pvm_bool* sourceOwned);
/*
	close audio file
*/
PVMAPI void PVMCALL PVMAudioClose(PVMAUDIO audio);
/*
	return length of audio file in milliseconds
*/
PVMAPI pvm_int32 PVMCALL PVMAudioGetLength(PVMAUDIO audio);


/*
	Play/stop, etc.
*/


/*
	Start playing audio
	returns chanel number used to play audio or -1 on error
	pass 0 to callbackPeriod to call callbackProc only at stop/pause
	callbackProc is called every callbackPeriod or if voice stopeed or paused (externaly or internally)
*/
#ifdef __cplusplus
PVMAPI pvm_int32 PVMCALL PVMAudioStart(PVMDEVICE device, PVMAUDIO audio, pvm_int32 loopCount, pvm_bool paused, pvm_int32 voiceNumber = PVM_VOICE_FREE, TVoiceCallbackProc callbackProc = 0, pvm_uint32 callbackPeriod = 0, void* callbackParam = 0);
#else
PVMAPI pvm_int32 PVMCALL PVMAudioStart(PVMDEVICE device, PVMAUDIO audio, pvm_int32 loopCount, pvm_bool paused, pvm_int32 voiceNumber, TVoiceCallbackProc callbackProc, pvm_uint32 callbackPeriod, void* callbackParam);
#endif

/*
	These functions allows to minimize delay and resources ussage whe you starting audio playback.
	PVMAudioCreateCache preallocate some buffers and make some initial calcukations.
*/
PVMAPI PVMAUDIOCACHE PVMCALL PVMAudioCreateCache(PVMDEVICE device, PVMAUDIO audio);
PVMAPI void PVMCALL PVMAudioFreeCache(PVMAUDIOCACHE audioCahce);
PVMAPI pvm_int32 PVMCALL PVMAudioCahceStart(PVMDEVICE device, PVMAUDIOCACHE audioCahce, pvm_int32 loopCount, pvm_bool paused, pvm_int32 voiceNumber, TVoiceCallbackProc callbackProc, pvm_uint32 callbackPeriod, void* callbackParam);
PVMAPI pvm_bool PVMCALL PVMIsAudioCahceStarted(PVMAUDIOCACHE audioCahce);

/*
	Audio options
*/
PVMAPI pvm_bool PVMCALL PVMGetAudioOption(PVMAUDIO audio, const pvm_char* optionName, void* optionVal, pvm_uint32* optionSize);
PVMAPI pvm_bool PVMCALL PVMSetAudioOption(PVMAUDIO audio, const pvm_char* optionName, void* optionVal, pvm_uint32 optionSize);

/*
	Voice control functions
*/

/*
	PVMIsVoiceFree returns non zero if chanel is free and can been used for playback
*/
PVMAPI pvm_bool PVMCALL PVMIsVoiceFree(PVMDEVICE device, pvm_uint32 chanelNum);

/*
	Stop voice playback
*/
PVMAPI void PVMCALL PVMVoiceStop(PVMDEVICE device, pvm_uint32 chanelNum);

/*
	Voice options
*/
PVMAPI pvm_bool PVMCALL PVMGetVoiceOption(PVMDEVICE device, pvm_uint32 chanelNum, const pvm_char* optionName, void* optionVal, pvm_uint32* optionSize);
PVMAPI pvm_bool PVMCALL PVMSetVoiceOption(PVMDEVICE device, pvm_uint32 chanelNum, const pvm_char* optionName, void* optionVal, pvm_uint32 optionSize);

/*
	Voice parameters - volume, panning, loopcount, rate, etc.
*/

PVMAPI pvm_bool PVMCALL PVMVoiceSetPanning(PVMDEVICE device, pvm_uint32 chanelNum, pvm_int32 value);
PVMAPI pvm_bool PVMCALL PVMVoiceSetVolume(PVMDEVICE device, pvm_uint32 chanelNum, pvm_int32 value);//0 - off, 256 - max volume
PVMAPI pvm_bool PVMCALL PVMVoiceSetLoopCount(PVMDEVICE device, pvm_uint32 chanelNum, pvm_int32 value);
PVMAPI pvm_bool PVMCALL PVMVoiceSetLoopInSamples(PVMDEVICE device, pvm_uint32 chanelNum, pvm_int64 loopFrom, pvm_int64 loopTo);
PVMAPI pvm_bool PVMCALL PVMVoiceSetPause(PVMDEVICE device, pvm_uint32 chanelNum, pvm_bool value);
PVMAPI pvm_bool PVMCALL PVMVoiceSetRenderSilentVoice(PVMDEVICE device, pvm_uint32 chanelNum, pvm_bool value);
PVMAPI pvm_bool PVMCALL PVMVoiceSetRate(PVMDEVICE device, pvm_uint32 chanelNum, pvm_int32 value);//

PVMAPI pvm_bool PVMCALL PVMVoiceGetPanning(PVMDEVICE device, pvm_uint32 chanelNum, pvm_int32* value);
PVMAPI pvm_bool PVMCALL PVMVoiceGetVolume(PVMDEVICE device, pvm_uint32 chanelNum, pvm_int32* value);//
PVMAPI pvm_bool PVMCALL PVMVoiceGetLoopCount(PVMDEVICE device, pvm_uint32 chanelNum, pvm_int32* value);
PVMAPI pvm_bool PVMCALL PVMVoiceGetLoopInSamples(PVMDEVICE device, pvm_uint32 chanelNum, pvm_int64* loopFrom, pvm_int64* loopTo);
PVMAPI pvm_bool PVMCALL PVMVoiceGetLoopInMS(PVMDEVICE device, pvm_uint32 chanelNum, pvm_int32* loopFrom, pvm_int32* loopTo);
PVMAPI pvm_bool PVMCALL PVMVoiceGetPause(PVMDEVICE device, pvm_uint32 chanelNum, pvm_bool* value);
PVMAPI pvm_bool PVMCALL PVMVoiceGetRenderSilentVoice(PVMDEVICE device, pvm_uint32 chanelNum, pvm_bool* value);
PVMAPI pvm_bool PVMCALL PVMVoiceGetRate(PVMDEVICE device, pvm_uint32 chanelNum, pvm_int32* value);//

PVMAPI pvm_bool PVMCALL PVMVoiceSetPositionMS(PVMDEVICE device, pvm_uint32 chanelNum, pvm_int32 value);
PVMAPI pvm_bool PVMCALL PVMVoiceGetPositionMS(PVMDEVICE device, pvm_uint32 chanelNum, pvm_int32* value);


PVMAPI pvm_bool PVMCALL PVMGetParamRange(pvm_uint32 paramId, pvm_int32* minValue, pvm_int32* maxValue, pvm_int32* defaultValue);

/*
	3d sound
*/

/*
	You can use flags defined in TPvm3DSupportFlags to control type of 3d sound system
*/
PVMAPI pvm_int32 PVMCALL PVMDeviceGet3dSupportFlags(PVMDEVICE device);
PVMAPI pvm_bool PVMCALL PVMDeviceChoose3d(PVMDEVICE device, pvm_int32 i3dType);

/*
	PVM3DGetRealizationType returns flags defined in TPvm3DSupportFlags
*/
PVMAPI pvm_int32 PVMCALL PVM3DGetRealizationType(PVMDEVICE device);

/*
	Enable/disable 3d mode
*/
PVMAPI pvm_bool PVMCALL PVM3DEnable(PVMDEVICE device);
PVMAPI void PVMCALL PVM3DDisable(PVMDEVICE device);

/*
	All changes in 3d, such as voice position, speed, dopler and other are applyed in PVM3DUpdate
	You should call PVM3DUpdate periodicaly in your "update" procedure
*/
PVMAPI void PVMCALL PVM3DUpdate(PVMDEVICE device);

/*
	You can choose prefered distance model from TPvmDistanceModel.
	Available disatnce model depends on type of 3d system.
	Call PVM3DGetSupportedDistanceModels to get list of available models.
*/
PVMAPI pvm_int32 PVMCALL PVM3DGetSupportedDistanceModels(PVMDEVICE device);
PVMAPI pvm_bool PVMCALL PVM3DSetDistanceModel(PVMDEVICE device, pvm_int32 model);
PVMAPI pvm_int32 PVMCALL PVM3DGetDistanceModel(PVMDEVICE device);

/*
	Enables/disables 3d for particular voice
*/
PVMAPI pvm_bool PVMCALL PVM3DControlEnable(PVMDEVICE device, pvm_int32 chanelNum);
PVMAPI pvm_bool PVMCALL PVM3DControlDisable(PVMDEVICE device, pvm_int32 chanelNum);

/*
	This function tells system to stop voice if it's level reaches zero due to it's distance from listener.
	This allows to free some voices and get more resource.
	Use with care.
*/
PVMAPI pvm_bool PVMCALL PVM3DSetStopOnDistance(PVMDEVICE device, pvm_int32 chanelNum, pvm_bool flag);
PVMAPI pvm_bool PVMCALL PVM3DGetStopOnDistance(PVMDEVICE device, pvm_int32 chanelNum, pvm_bool* flag);

/*
	Next functions are scalar type dependent.
	If you call function that uses scalar wich from current 3d system realization, automatic conversation will be done.
*/

/*
	Floating point functions:
*/

/*
	Listener 3d settings and common stuff
*/
PVMAPI pvm_bool PVMCALL PVM3DSetListenerPositionF(PVMDEVICE device, float x, float y, float z);
PVMAPI pvm_bool PVMCALL PVM3DSetListenerVelocityF(PVMDEVICE device, float x, float y, float z);
PVMAPI pvm_bool PVMCALL PVM3DSetListenerOrientationF(PVMDEVICE device, float xFront, float yFront, float zFront, float xTop, float yTop, float zTop);
PVMAPI pvm_bool PVMCALL PVM3DSetDopplerFactorF(PVMDEVICE device, float factor);
PVMAPI pvm_bool PVMCALL PVM3DSetUnitSizeF(PVMDEVICE device, float size);

PVMAPI pvm_bool PVMCALL PVM3DGetListenerPositionF(PVMDEVICE device, float* x, float* y, float* z);
PVMAPI pvm_bool PVMCALL PVM3DGetListenerVelocityF(PVMDEVICE device, float* x, float* y, float* z);
PVMAPI pvm_bool PVMCALL PVM3DGetListenerOrientationF(PVMDEVICE device, float* xFront, float* yFront, float* zFront, float* xTop, float* yTop, float* zTop);
PVMAPI pvm_bool PVMCALL PVM3DGetDopplerFactorF(PVMDEVICE device, float* factor);
PVMAPI pvm_bool PVMCALL PVM3DGetUnitSizeF(PVMDEVICE device, float* size);

/*
	Voice 3d settings
*/
PVMAPI pvm_bool PVMCALL PVM3DSetVoicePositionF(PVMDEVICE device, pvm_int32 chanelNum, float x, float y, float z);
PVMAPI pvm_bool PVMCALL PVM3DSetVoiceVelocityF(PVMDEVICE device, pvm_int32 chanelNum, float x, float y, float z);
PVMAPI pvm_bool PVMCALL PVM3DSetVoiceDirectionF(PVMDEVICE device, pvm_int32 chanelNum, float x, float y, float z);
PVMAPI pvm_bool PVMCALL PVM3DSetVoiceMinDistanceF(PVMDEVICE device, pvm_int32 chanelNum, float d);
PVMAPI pvm_bool PVMCALL PVM3DSetVoiceMaxDistanceF(PVMDEVICE device, pvm_int32 chanelNum, float d);
PVMAPI pvm_bool PVMCALL PVM3DSetRolloffFactorF(PVMDEVICE device, pvm_int32 chanelNum, float factor);

PVMAPI pvm_bool PVMCALL PVM3DGetVoicePositionF(PVMDEVICE device, pvm_int32 chanelNum, float* x, float* y, float* z);
PVMAPI pvm_bool PVMCALL PVM3DGetVoiceVelocityF(PVMDEVICE device, pvm_int32 chanelNum, float* x, float* y, float* z);
PVMAPI pvm_bool PVMCALL PVM3DGetVoiceDirectionF(PVMDEVICE device, pvm_int32 chanelNum, float* x, float* y, float* z);
PVMAPI pvm_bool PVMCALL PVM3DGetVoiceMinDistanceF(PVMDEVICE device, pvm_int32 chanelNum, float* d);
PVMAPI pvm_bool PVMCALL PVM3DGetVoiceMaxDistanceF(PVMDEVICE device, pvm_int32 chanelNum, float* d);
PVMAPI pvm_bool PVMCALL PVM3DGetRolloffFactorF(PVMDEVICE device, pvm_int32 chanelNum, float* factor);

/*
	Fixed point functions:
*/

/*
	Listener 3d settings and common stuff
*/
PVMAPI pvm_bool PVMCALL PVM3DSetListenerPositionX(PVMDEVICE device, pvm_int32 x, pvm_int32 y, pvm_int32 z);
PVMAPI pvm_bool PVMCALL PVM3DSetListenerVelocityX(PVMDEVICE device, pvm_int32 x, pvm_int32 y, pvm_int32 z);
PVMAPI pvm_bool PVMCALL PVM3DSetListenerOrientationX(PVMDEVICE device, pvm_int32 xFront, pvm_int32 yFront, pvm_int32 zFront, pvm_int32 xTop, pvm_int32 yTop, pvm_int32 zTop);
PVMAPI pvm_bool PVMCALL PVM3DSetDopplerFactorX(PVMDEVICE device, pvm_int32 factor);
PVMAPI pvm_bool PVMCALL PVM3DSetUnitSizeX(PVMDEVICE device, pvm_int32 size);

PVMAPI pvm_bool PVMCALL PVM3DGetListenerPositionX(PVMDEVICE device, pvm_int32* x, pvm_int32* y, pvm_int32* z);
PVMAPI pvm_bool PVMCALL PVM3DGetListenerVelocityX(PVMDEVICE device, pvm_int32* x, pvm_int32* y, pvm_int32* z);
PVMAPI pvm_bool PVMCALL PVM3DGetListenerOrientationX(PVMDEVICE device, pvm_int32* xFront, pvm_int32* yFront, pvm_int32* zFront, pvm_int32* xTop, pvm_int32* yTop, pvm_int32* zTop);
PVMAPI pvm_bool PVMCALL PVM3DGetDopplerFactorX(PVMDEVICE device, pvm_int32* factor);
PVMAPI pvm_bool PVMCALL PVM3DGetUnitSizeX(PVMDEVICE device, pvm_int32* size);

/*
	Voice 3d settings
*/
PVMAPI pvm_bool PVMCALL PVM3DSetVoicePositionX(PVMDEVICE device, pvm_int32 chanelNum, pvm_int32 x, pvm_int32 y, pvm_int32 z);
PVMAPI pvm_bool PVMCALL PVM3DSetVoiceVelocityX(PVMDEVICE device, pvm_int32 chanelNum, pvm_int32 x, pvm_int32 y, pvm_int32 z);
PVMAPI pvm_bool PVMCALL PVM3DSetVoiceDirectionX(PVMDEVICE device, pvm_int32 chanelNum, pvm_int32 x, pvm_int32 y, pvm_int32 z);
PVMAPI pvm_bool PVMCALL PVM3DSetVoiceMinDistanceX(PVMDEVICE device, pvm_int32 chanelNum, pvm_int32 d);
PVMAPI pvm_bool PVMCALL PVM3DSetVoiceMaxDistanceX(PVMDEVICE device, pvm_int32 chanelNum, pvm_int32 d);
PVMAPI pvm_bool PVMCALL PVM3DSetRolloffFactorX(PVMDEVICE device, pvm_int32 chanelNum, pvm_int32 factor);

PVMAPI pvm_bool PVMCALL PVM3DGetVoicePositionX(PVMDEVICE device, pvm_int32 chanelNum, pvm_int32* x, pvm_int32* y, pvm_int32* z);
PVMAPI pvm_bool PVMCALL PVM3DGetVoiceVelocityX(PVMDEVICE device, pvm_int32 chanelNum, pvm_int32* x, pvm_int32* y, pvm_int32* z);
PVMAPI pvm_bool PVMCALL PVM3DGetVoiceDirectionX(PVMDEVICE device, pvm_int32 chanelNum, pvm_int32* x, pvm_int32* y, pvm_int32* z);
PVMAPI pvm_bool PVMCALL PVM3DGetVoiceMinDistanceX(PVMDEVICE device, pvm_int32 chanelNum, pvm_int32* d);
PVMAPI pvm_bool PVMCALL PVM3DGetVoiceMaxDistanceX(PVMDEVICE device, pvm_int32 chanelNum, pvm_int32* d);
PVMAPI pvm_bool PVMCALL PVM3DGetRolloffFactorX(PVMDEVICE device, pvm_int32 chanelNum, pvm_int32* factor);

#if defined(__cplusplus)
}
#endif/*__cplusplus*/

/*
	C++  interfaces to read and write from user defined streams.
*/

#if defined(__cplusplus)
	class IPvmBaseStream
	{
	public:
		virtual pvm_bool Seek(pvm_file_size pos, TPvmSeek origin) = 0;
		virtual pvm_file_size Tell() = 0;
		virtual void Close() = 0;
		virtual pvm_file_size Size() = 0;
		virtual pvm_bool Seekable() = 0;//return non zero if Seek can be performed

		virtual ~IPvmBaseStream() {};
	};

	class IPvmInStream : public IPvmBaseStream
	{
	public:
		virtual pvm_size Read(void *buf, pvm_size size) = 0;
		virtual IPvmInStream* OpenCopy() = 0;//return NULL if not supported - so only one chanel can play at once
		virtual ~IPvmInStream() {};
		virtual pvm_bool Eof() = 0;
	};

	class IPvmOutStream: public IPvmBaseStream
	{
	public:
		virtual pvm_size Write(void *buf, pvm_size size) = 0;
		virtual ~IPvmOutStream() {};
	};

	/*
		Open audio file
    */
	PVMAPI PVMAUDIO PVMCALL PVMAudioOpenStream(IPvmInStream *stream, pvm_uint32 options, pvm_bool* sourceOwned);
#endif/*__cplusplus*/

#endif/*__PVMAPI_H__*/

